/**
 *
 */
package com.fc.test.controller.events;

import javax.servlet.http.HttpServletRequest;

import com.fc.test.common.domain.AjaxResult;
import com.fc.test.controller.HomeController;
import com.fc.test.model.auto.TsysUser;
import com.fc.test.model.custom.TEventsTurntable;
import com.fc.test.model.custom.TUser;
import com.fc.test.service.UserService;
import com.fc.test.shiro.config.MobilePhonePasswordToken;
import com.fc.test.util.MD5Util;
import com.fc.test.util.ProbabilityUtils;
import com.fc.test.util.StringUtils;
import com.google.code.kaptcha.Constants;
import io.swagger.annotations.Api;

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import com.fc.test.common.base.BaseController;
import com.fc.test.model.custom.TitleVo;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.util.Date;
import java.util.List;

/**
 * 大转盘抽奖控制器
 *
 * @author xugang
 */
@Controller
@Api(value = "大转盘抽奖")
@RequestMapping("TurntableController")
public class TurntableController extends BaseController {
    private static Logger logger = LoggerFactory.getLogger(HomeController.class);

    // 跳转页面参数
    private String prefix = "events/turntable";

    @Autowired
    private UserService userService;

    /**
     * 进入大转盘活动页面(不需要登录验证)
     *
     * @return
     */
    @GetMapping("turntable")
    public String turntable(HttpServletRequest request, Model model) {
        logger.info("===== 进入大转盘活动页面, URL:{}", "/TurntableController/turntable");
        return prefix + "/turntable";
    }

    /**
     * 开始抽奖
     *
     * @param request
     * @return
     */
    @PostMapping("start")
    @ResponseBody
    public AjaxResult begin(HttpServletRequest request, Model model) {
        logger.info("===== 用户点击抽奖按钮开始抽奖, URL:{}", "/TurntableController/start");
        try {
            if ((null != SecurityUtils.getSubject() && SecurityUtils.getSubject().isAuthenticated())) {
                String mobilePhone = ((TUser) SecurityUtils.getSubject().getPrincipal()).getMobilePhone();
                TEventsTurntable turntable = userService.queryRecordsByMobilePhone(mobilePhone);
                if (turntable != null) {
                    return AjaxResult.error(501, "不能重复参加抽奖");
                }
                int probability = ProbabilityUtils.generateProbability();
                return AjaxResult.successData(200, probability); // 第二个参数可作为中奖概率传给页面
            } else {
                logger.warn("===== 抽奖前登录验证失败，跳转至用户登录页面");
                return error("用户未登录");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return error();
    }

    /**
     * 保存抽奖记录
     *
     * @param tEventsTurntable
     * @return
     */
    @PostMapping("addwinningrecords")
    @ResponseBody
    public AjaxResult saveWinningRecords(TEventsTurntable tEventsTurntable) {
        logger.info("===== 保存用户抽奖记录, URL:{}", "/TurntableController/addwinningrecords");
        TUser tUser = (TUser) SecurityUtils.getSubject().getPrincipal();
        TEventsTurntable turntable = userService.queryRecordsByMobilePhone(tUser.getMobilePhone());
        if (turntable != null) {
            return AjaxResult.error(502, "用户抽奖记录已存在");
        }
        tEventsTurntable.setMobilePhone(tUser.getMobilePhone());
        tEventsTurntable.setUsername(tUser.getUsername());
        tEventsTurntable.setAwardTime(new Date());
        int result = userService.saveWinningRecords(tEventsTurntable);
        if (result == 1) {
            return success();
        }
        return error();
    }

    /**
     * 用户登录页面
     *
     * @return
     */
    @GetMapping("login")
    public String login(HttpServletRequest request, Model model) {
        logger.info("===== 进入用户登录页面,登录之后才可以参加活动， URL:{}", "/TurntableController/login");
        try {
            if ((null != SecurityUtils.getSubject() && SecurityUtils.getSubject().isAuthenticated()) || SecurityUtils.getSubject().isRemembered()) {
                logger.info("===== 用户已经登录，不需要重复登录，跳转到活动页面");
                // TODO 设置中奖概率
                return prefix + "/turntable";
            } else {
                logger.info("===== 用户未登录，填写用户名密码进行登录");
                return prefix + "/login";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return prefix + "/login";
    }

    /**
     * 用户登陆验证
     *
     * @param request
     * @return
     */
    @PostMapping("submitlogin")
    public ModelAndView loginReal(TUser user, String code, RedirectAttributes redirectAttributes, boolean rememberMe, Model model, HttpServletRequest request) {
        logger.info("===== 对用户[{}]进行登录验证.. URL:{}", user.getMobilePhone(), "/TurntableController/submitlogin");
        ModelAndView view = new ModelAndView();
        String scode = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        //判断验证码
        if (StringUtils.isNotEmpty(code) && scode.equals(code)) {
            String mobilePhone = user.getMobilePhone(); // 此处已手机号码作为用户唯一标识
            Subject currentUser = SecurityUtils.getSubject();
            if (!currentUser.isAuthenticated()) {
                MobilePhonePasswordToken token = new MobilePhonePasswordToken(mobilePhone, user.getPassword());
                try {
                    if (rememberMe) {
                        token.setRememberMe(true);
                    }
                    currentUser.login(token);
                    setTitle(model, new TitleVo("欢迎页面", "首页", true, "欢迎进入", true, false));
                } catch (UnknownAccountException uae) {
                    logger.info("对用户[" + mobilePhone + "]进行登录验证..验证未通过,未知账户");
                    redirectAttributes.addFlashAttribute("message", "未知账户");
                } catch (IncorrectCredentialsException ice) {
                    logger.info("对用户[" + mobilePhone + "]进行登录验证..验证未通过,错误的凭证");
                    redirectAttributes.addFlashAttribute("message", "用户名或密码不正确");
                } catch (LockedAccountException lae) {
                    logger.info("对用户[" + mobilePhone + "]进行登录验证..验证未通过,账户已锁定");
                    redirectAttributes.addFlashAttribute("message", "账户已锁定");
                } catch (ExcessiveAttemptsException eae) {
                    logger.info("对用户[" + mobilePhone + "]进行登录验证..验证未通过,错误次数过多");
                    redirectAttributes.addFlashAttribute("message", "用户名或密码错误次数过多");
                } catch (AuthenticationException ae) {
                    //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
                    logger.info("对用户[" + mobilePhone + "]进行登录验证..验证未通过,堆栈轨迹如下");
                    ae.printStackTrace();
                    redirectAttributes.addFlashAttribute("message", "用户名或密码不正确");
                }
            }
        } else {
            redirectAttributes.addFlashAttribute("message", "验证码不正确");
        }
        view.setViewName("redirect:/TurntableController/login");
        return view;
    }

    /**
     * 进入用户注册页面
     *
     * @return
     */
    @GetMapping("register")
    public String register(HttpServletRequest request, Model model) {
        logger.info("===== 进入用户注册页面， URL:{}", "/TurntableController/register");
        return prefix + "/register";
    }

    /**
     * 用户提交注册
     *
     * @return
     */
    @PostMapping("submitregister")
    @ResponseBody
    public AjaxResult registerReal(String mobilePhone, String username, String password, String email, String code, HttpServletRequest request) {
        logger.info("===== 新用户注册 URL:{}", mobilePhone, "/TurntableController/submitregister");
        String scode = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        //判断验证码
        if (StringUtils.isNotEmpty(code) && scode.equals(code)) {
            TUser tUser = userService.queryByMobilePhone(mobilePhone);
            if (tUser != null) {
                return error("手机号码已注册");
            }
            password = StringUtils.isBlank(password) == true ? "123456789" : password; // 默认密码
            int result = userService.save(mobilePhone, username, MD5Util.encode(password), email, 0, 0);
            if (result != 1) {
                return error("用户注册失败");
            } else {
                logger.info("===== 新用户注册成功,跳转到登录页面");
                return success(password);
            }
        } else {
            return error("验证码不正确");
        }
    }

}
